
/*
 *
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 *  These are the four essential freedoms with GNU GPL software:
 *  1: freedom to run the program, for any purpose
 *  2: freedom to study how the program works, and change it to make it do what you wish
 *  3: freedom to redistribute copies to help your Free Software girlfriends and friends
 *  4: freedom to distribute copies of your modified versions to your Free Software girlfriends and friends
 *   ,           ,
 *  /             \
 * ((__-^^-,-^^-__))
 * `-_---'  `---_-'
 *  `--|o`   'o|--'
 *      \  `  /
 *       ): :(
 *       :o_o:
 *        "-"
 */

#include "config.h"

#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>

#include "main.h"
#include "mpool.h"
#include "splay-tree.h"
#include "uniqstring.h"

static struct mpool *uniqstring_pool = NULL;

static splay_tree gustring = NULL;

/* The type of a function used to allocate memory for tree root and
   node structures.  The first argument is the number of bytes needed;
   the second is a data pointer the splay tree functions pass through
   to the allocator.  This function must never return zero.  */
static void *uniqstring_splay_tree_allocate_fn (size_t n, void *data);

/* The type of a function used to free memory allocated using the
   corresponding splay_tree_allocate_fn.  The first argument is the
   memory to be freed; the latter is a data pointer the splay tree
   functions pass through to the freer.  */
static void uniqstring_splay_tree_deallocate_fn (void *pointer, void *data);

/* The type of a function used to deallocate any resources associated
   with the key.  */
static void uniqstring_splay_tree_delete_key_fn (splay_tree_key keydata);

/* The type of a function used to deallocate any resources associated
   with the value.  */
static void uniqstring_splay_tree_delete_value_fn (splay_tree_value
						   valuedata);

char *
uniqstring (char *s)
{
  splay_tree_node spn = (splay_tree_node) 0;
 char *buf;
 
  spn = splay_tree_lookup ((splay_tree) gustring, (splay_tree_key) s);


  if (spn) {
   return (char *)spn->key;
  }
 
  buf = mpool_pool_malloc (uniqstring_pool,strlen(s)+1);
  memset (buf,0,strlen(s)+1);

      /* copy (dest, src, n); strcpy() is a safety bug. */
      (void) memmove ((void *) buf, (const void *) s, (size_t) strlen(s));

  spn = splay_tree_insert (gustring,	/* splay_tree */
				    (splay_tree_key) buf,	/* index */
				    (splay_tree_value) 0	/* unused */
);

  return buf;
}

void
uniqstring_reset (void)
{
  mpool_pool_delete (uniqstring_pool);
  uniqstring_pool = mpool_pool_new ();

      /* indexed on (char *) */
     gustring = splay_tree_new_with_allocator (splay_tree_compare_strings,	/* splay_tree_compare_fn */
						   uniqstring_splay_tree_delete_key_fn,	/* splay_tree_delete_key_fn */
						   uniqstring_splay_tree_delete_value_fn,	/* splay_tree_delete_value_fn */
						   uniqstring_splay_tree_allocate_fn,	/* splay_tree_allocate_fn */
						   uniqstring_splay_tree_deallocate_fn,	/* splay_tree_deallocate_fn */
						   (void *) 0	/* allocate-data */
	);

  return;
}

/* The type of a function used to allocate memory for tree root and
   node structures.  The first argument is the number of bytes needed;
   the second is a data pointer the splay tree functions pass through
   to the allocator.  This function must never return zero.  */
static void *
uniqstring_splay_tree_allocate_fn (size_t n, void *data)
{
  /* pacify gcc */
  if (data)
    {
    }
  return ((void *)mpool_pool_malloc (uniqstring_pool , (size_t) n));
}

/* The type of a function used to free memory allocated using the
   corresponding splay_tree_allocate_fn.  The first argument is the
   memory to be freed; the latter is a data pointer the splay tree
   functions pass through to the freer.  */
static void
uniqstring_splay_tree_deallocate_fn (void *pointer, void *data)
{
  /* pacify gcc */
  if (data)
    {
    }
 if (pointer) {}
  return;
}

/* The type of a function used to deallocate any resources associated
   with the key.  */
static void
uniqstring_splay_tree_delete_key_fn (splay_tree_key keydata)
{
  /* key is a (char *) deallocated via mpool() system */
  if (keydata)
    {
    }
  return;
}

/* The type of a function used to deallocate any resources associated
   with the value.  */
static void
uniqstring_splay_tree_delete_value_fn (splay_tree_value valuedata)
{
  /* value is unused */
  if (valuedata)
    {
    }
  return;
}

/* End. */
